#include "sfs-aa.h"

// horrible kludge to get the bdd information from Anders to be usable
// by PtsSet
//
bdd pdom;
bddPair *g2p;
vector<bdd> bdd_off, bdd_xlt;

bdd get_bdd(u32 x)
{
  if (x >= bdd_xlt.size()) { bdd_xlt.resize(x+1,bddfalse); }
  if (bdd_xlt[x] == bddfalse) { bdd_xlt[x] = fdd_ithvar(0,x); }
  return bdd_xlt[x];
}

// and same kludge so PtsGraph can access o2p[]
//
vector<u32> o2p; // object -> access equivalence partition

bool SFS::runOnModule(Module &M)
{
	errs() << "SFS runOnModule\n";
  reset_time();
  base_mem = get_mem_usage(true);

  run_init(&M);

  sfs_id();
  solve();

  return false;
}

void SFS::print(llvm::raw_ostream &O, const Module *M) const 
{
#if 0
	O << ">>>>>>>>>>>>> SFS Print <<<<<<<<<<<<<\n";
	O << "============= Andres Ouput =========\n";
	PRE.print_cons_graph(1,1,&O);
    O << "============= SFS output ===========\n";
    dfg.print(&O);
	O << "============= Points-to =============\n";

	FORN(i, top.size()) {
		O << i << ". ";
		top[i].print(&O);
	}
	O << ">>>>>>>>>>>>> SFS Print <<<<<<<<<<<<<\n";
#else
	O << ">>>>>>>>>>>>> SFS Print <<<<<<<<<<<<<\n";
	O << "============= Andres Ouput =========\n";
	PRE.print_cons_graph(1,1,&O);
    O << "============= SFS output ===========\n";
    dfg.print();

	O << "============= Points-to =============\n";

	FORN(i, top.size()) {
		PRE.print_node_now(i);
		O << ".................... -> ";
		PtsSet ptsTemp = top[i];
      	bdd p = ptsTemp.pts;
      
	  	while (p != bddfalse) {
			int x = fdd_scanvar(p,0);
			p -= fdd_ithvar(0,x);
			PRE.print_node_now(x);
      	}

		O << "\n";
	}
	O << ">>>>>>>>>>>>> SFS Print <<<<<<<<<<<<<\n";
#endif
}

void SFS::releaseMemory() {}

//Pass registration
char SFS::ID= 0;
RegisterPass<SFS> X("sfs-aa",
		    "sparse flow-sensitive pointer analysis");
